package com.huanxing.cloud.auth.handler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.huanxing.cloud.common.core.constant.CommonConstants;
import com.huanxing.cloud.common.core.constant.SecurityConstants;
import com.huanxing.cloud.common.core.util.IpUtils;
import com.huanxing.cloud.upms.common.entity.SysLoginLog;
import com.huanxing.cloud.upms.common.feign.FeignSysLoginLogService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

/**
 * @description: 用户登录失败监听器事件
 * @author lijx
 * @date 2022/5/20 22:30
 * @version 1.0
 */
@Slf4j
@Component
@AllArgsConstructor
public class HxAuthencationFailureListener
    implements ApplicationListener<AbstractAuthenticationFailureEvent> {
  private final FeignSysLoginLogService feignSysLoginLogService;

  @Override
  public void onApplicationEvent(AbstractAuthenticationFailureEvent event) {
    log.info(
        "用户：{} 登录失败，异常：{}",
        event.getAuthentication().getPrincipal(),
        event.getException().getLocalizedMessage());
    HttpServletRequest request =
        ((ServletRequestAttributes)
                Objects.requireNonNull(RequestContextHolder.getRequestAttributes()))
            .getRequest();
    // 异步处理登录日志
    CompletableFuture.runAsync(
        () -> {
          String agent = request.getHeader("User-Agent").toLowerCase();
          UserAgent ua = UserAgentUtil.parse(agent);
          SysLoginLog sysLoginLog = new SysLoginLog();
          sysLoginLog.setStatus(CommonConstants.LOGIN_LOG_STATUS_0);
          sysLoginLog.setIpAddr(ServletUtil.getClientIP(request));
          sysLoginLog.setLocation(IpUtils.getWhoisAddress(sysLoginLog.getIpAddr()));
          sysLoginLog.setUserName(event.getAuthentication().getPrincipal().toString());
          sysLoginLog.setOs(ua.getOs().toString());
          sysLoginLog.setBrowser(ua.getBrowser().toString());
          sysLoginLog.setMsg(
              StrUtil.format(
                  "用户：{} 登录失败，异常：{}",
                  event.getAuthentication().getPrincipal(),
                  event.getException().getLocalizedMessage()));

          feignSysLoginLogService.save(sysLoginLog, SecurityConstants.SOURCE_IN);
        });
  }
}
